import { Tools } from './../../../../tools/tools';
import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core';
import { NzUploadFile } from 'ng-zorro-antd';
import { Observable, Observer } from 'rxjs';
import { BaseFieldComponent } from '../base-field/base-field.component';
import { PermitConfig, PermitConfigId } from '../../../models';

@Component({
  selector: 'zepride-files',
  templateUrl: './files.component.html',
  styleUrls: ['./files.component.less', '../field.common.less']
})
export class FilesComponent extends BaseFieldComponent implements OnInit, AfterViewInit, OnDestroy {

  mutipleFile: MutipleFile[] = [];
  fileFormats = [];
  permitConfig: PermitConfig[] = [
    { mode: 'query', permitId: '查看', permitName: '', authObjectId: '' },
    { mode: 'edit', permitId: '编辑', permitName: '', authObjectId: '' }
  ];
  loading = false;
  isAuthorized = true;
  fileObj: { name?: string; url?: string; fileType?: string; } = {};
  previewImage: string | undefined = '';
  previewVisible = false;

  ngOnInit(): void {
    this.mutipleFile = this.componentData.extends.fields;
    if (this.bindData) {
      if (this.bindData instanceof Array) {
        this.mutipleFile = this.bindData;
      } else {
        this.fileObj = this.bindData;
      }
    }

    this.mutipleFile || (this.mutipleFile = []);
    this.mutipleFile.map(x => {
      x.fileList || (x.fileList = []);
    });

    this.fileFormats = this.componentData.extends.fileFormats;
    this.fileFormats || (this.fileFormats = []);
  }

  ngAfterViewInit() {
    setTimeout(() => {
      const authData = this.setAuthorityData();
      this.zeprideAuthorityData = {
        ...authData,
        afterChecked: this.afterAuthChecked.bind(this)
      };
    }, 0);
    this.registerModelChange();
  }

  beforeUpload = (file: NzUploadFile, _fileList: NzUploadFile[]) => {
    return new Observable((observer: Observer<boolean>) => {
      console.log('beforeUpload', this.fileFormats, file.type);
      let checkResult = false;
      if (this.fileFormats.length == 0) {
        checkResult = true;
      }

      if (this.fileFormats.find(x => x === 'images')) {
        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/bmp';

        if (isJpgOrPng) {
          checkResult = true;
        }
      }

      if (this.fileFormats.find(x => x === 'word')) {
        const r = (file.type.indexOf('application/msword') > -1) ||
          (file.type.indexOf('application/vnd.openxmlformats-officedocument.wordprocessingml.document') > -1);
        if (r) {
          checkResult = true;
        }
      }
      if (this.fileFormats.find(x => x === 'excel')) {
        const r = file.type.indexOf('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') > -1;
        if (r) {
          checkResult = true;
        }
      }
      if (this.fileFormats.find(x => x === 'zip')) {
        const r = file.type.indexOf('application/x-zip-compressed') > -1;
        if (r) {
          checkResult = true;
        }
      }
      if (this.fileFormats.find(x => x === 'pdf')) {
        const r = file.type.indexOf('pdf') > -1;
        if (r) {
          checkResult = true;
        }
      }
      if (!checkResult) {
        this.msg.error('文件格式错误!');
        observer.complete();
        return;
      }
      observer.next(checkResult);
      observer.complete();
    });
  }

  handleChange(info: { file: NzUploadFile }, item): void {
    switch (info.file.status) {
      case 'uploading':
        this.loading = true;
        break;
      case 'done':
        this.getBase64(info.file.originFileObj, (img: string) => {
          this.loading = false;
          const fobj: any = {
            uid: Tools.GetGuid(),
            name: info.file.name,
            url: `${this.uploadService.uploadUrl}${info.file.response.fileUrl}`,
            status: 'done',
            fileType: info.file.type,
            index: item.fileList.length
          };
          if (fobj.name.length > 10) {
            fobj.shortName = fobj.name.substr(0, 10) + '...';
          } else {
            fobj.shortName = fobj.name;
          }
          item.fileList.push(fobj);
          this.setBindData(this.mutipleFile);
          this.msg.success(`${info.file.name} 上传成功！`);
        });
        break;
      case 'error':
        this.msg.error('Network error');
        this.loading = false;
        break;
    }
  }

  handleChangeOne(info: { file: NzUploadFile }): void {
    switch (info.file.status) {
      case 'uploading':
        this.loading = true;
        break;
      case 'done':
        this.getBase64(info.file.originFileObj, (img: string) => {
          this.loading = false;
          this.fileObj = {
            url: `${this.uploadService.uploadUrl}${info.file.response.fileUrl}`,
            name: info.file.name,
            fileType: info.file.type
          };
          this.setBindData(this.fileObj);
          this.msg.success(`${info.file.name} 上传成功！`);
        });
        break;
      case 'error':
        this.msg.error('Network error');
        this.loading = false;
        break;
    }
  }

  registerModelChange() {
    this.modelChange$ = this.engineService.dataModelChange$.subscribe(data => {
      let componentFields = [];
      if (this.componentData.bindField) {
        componentFields = this.componentData.bindField.split('.');
      }
      if (data.identifyId !== this.componentData.identifyId && componentFields.indexOf(data.bindField) > -1) {
        const fileData = this.dataModel[this.componentData.bindField];
        if (fileData instanceof Array) {
          this.mutipleFile = fileData;
        } else {
          this.fileObj = fileData;
        }
      }
    });
  }

  private getBase64(img: File, callback: (img: string) => void): void {
    const reader = new FileReader();
    reader.addEventListener('load', () => callback(reader.result.toString()));
    reader.readAsDataURL(img);
  }

  cleanUploadFile() {
    this.componentData.defaultValue = '';
    this.fileObj = {};
    this.setBindData(this.fileObj);
  }

  delImageItem(item, index) {
    item.fileList.splice(index, 1);
  }

  handlePreview = async (file) => {
    this.previewImage = file.url;
    this.previewVisible = true;
  }

  downloadFile(item) {
    window.open(item.url);
  }

  afterAuthChecked(params: {
    permitId: PermitConfigId;
    isAuthorized: boolean;
  }) {
    if (!params.isAuthorized) {
      this.isAuthorized = false;
    }
  }

  getChangeLogSource() {
    if (!this.dataChangeLog.sourceValue) {
      return '';
    }

    if (Array.isArray(this.dataChangeLog.sourceValue)) {
      return this.dataChangeLog.sourceValue.map(item => {
        return item.fileList.map(x => x.name).join(',')
      }).join(',');
    }

    if (typeof (this.dataChangeLog.sourceValue) == 'object') {
      return this.dataChangeLog.sourceValue.name;
    }

    return this.dataChangeLog.sourceValue;
  }

  getChangeLogTarget() {
    if (!this.dataChangeLog.targetValue) {
      return '';
    }
    if (Array.isArray(this.dataChangeLog.targetValue)) {
      return this.dataChangeLog.targetValue.map(item => {
        return item.fileList.map(x => x.name).join(',')
      }).join(',');
    }
    if (typeof (this.dataChangeLog.targetValue) == 'object') {
      return this.dataChangeLog.targetValue.name;
    }
    return this.dataChangeLog.targetValue;
  }

  ngOnDestroy() {
    if (this.modelChange$) {
      this.modelChange$.unsubscribe();
    }
  }
}

interface MutipleFile {
  title: string;
  id: string;
  maxCount: number;
  fileList: {
    fileType: string;
    name: string;
    shortName: string;
    url: string;
  }[];
}
